#if PS_GREASE
uint16_t ps_grease_thd;
uint16_t ps_grease_add;
uint16_t last_ps_status;
#endif
#if PS_DYN_K
uint32_t dynk_thd_low = 0;
uint32_t dynk_thd_high = 0;
int dynk_low_offset;
int dynk_high_offset;

#endif  /*PS_DYN_K*/
#if PS_GREASE
bool mn_grease_algr( uint16_t ps_status)
{
  uint16_t i2c_read_data[2];
  uint16_t now_h_thd, base_l_thd, base_h_thd;
#if PS_DYN_K
  base_l_thd = dynk_thd_low;
  base_h_thd = dynk_thd_high;
#else
  base_l_thd = mn_sensor_ps_low_threshold;
  base_h_thd = mn_sensor_ps_high_threshold;
#endif

  mn_sensor_I2C_Read(DEVREG_PS_IHTL, i2c_read_data, 2);
  now_h_thd = (uint16_t)((i2c_read_data[1] << 8) | i2c_read_data[0]);
  Serial.printf("[mn_grease_algr]: now_h_thd=%u\n", now_h_thd);
  if (now_h_thd == base_h_thd)
  {
    if (ps_status == 0)
    {
      set_psensor_intr_threshold( base_l_thd, ps_grease_thd);
      mn_sensor_I2C_Write(DEVREG_PS_STATUS, (MN_CMP_RESET | MN_LOCK) );
    }
  }
  else if (now_h_thd == ps_grease_thd)
  {
    if (ps_status == 0)
    {
#if PS_DYN_K
      mn_sensor_ps_dynk_min_ps_raw_data = 65535;
      set_psensor_intr_threshold( ps_grease_thd, 65535 );
#else
      set_psensor_intr_threshold( (base_l_thd + ps_grease_add), (base_h_thd + ps_grease_add) );

#endif
      mn_sensor_read_ps_thd();
      return false;
    }
    else
      set_psensor_intr_threshold( base_l_thd, base_h_thd );
  }
  mn_sensor_read_ps_thd();
  return true;
}
#endif
static int  mn78_write_global_variable(void)
{
  int ret = 0;
  uint8_t buf_block[7];
  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN) );
  mn_sensor_I2C_Write( DEVREG_PS_STATUS, (MN_CMP_RESET | MN_LOCK) );
  mn_sensor_I2C_Write( DEVREG_PS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );
  mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RESET | MN_LOCK) );
  mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );

  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_OFF | MN_RESETN_RESET) );
  mn_sensor_I2C_Write( DEVREG_PS_OFSL, (uint8_t)(mn_sensor_ps_ps_offset & 0xff) );
  mn_sensor_I2C_Write( DEVREG_PS_OFSH, ((mn_sensor_ps_ps_offset & 0xff00) >> 8) );
  mn_sensor_I2C_Write( DEVREG_ALS_OFSL, (uint8_t)(mn_sensor_als_als_offset & 0xff) );
  mn_sensor_I2C_Write( DEVREG_ALS_OFSH, ((mn_sensor_als_als_offset & 0xff00) >> 8) );

  select_pixel_scale();
#if PS_DYN_K
  set_psensor_intr_threshold( mn_sensor_ps_ps_max_ct, mn_sensor_ps_ps_max_ct + 1);
#else
  set_psensor_intr_threshold( mn_sensor_ps_low_threshold, mn_sensor_ps_high_threshold);
#endif
  set_lsensor_intr_threshold( mn_sensor_als_low_threshold, mn_sensor_als_low_threshold);
  mn_sensor_int_conf();

  write_pxl_sel(); //pixel selection
  write_als_conf();  //als config
  write_ps_conf();  //ps config
  write_ag_conf();
  set_ag_threshold( DEVREG_ALS_AG_H2M_THL, mn_sensor_als_als_ag_h2m_thd);
  set_ag_threshold( DEVREG_ALS_AG_M2H_THL, mn_sensor_als_als_ag_m2h_thd);
  set_ag_threshold( DEVREG_ALS_AG_M2L_THL, mn_sensor_als_als_ag_m2l_thd);
  set_ag_threshold( DEVREG_ALS_AG_L2M_THL, mn_sensor_als_als_ag_l2m_thd);
  if (mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
  {
    buf_block[0] = mn_sensor_als_als_aenh_ll | mn_sensor_als_als_aintt_ll;
    buf_block[1] = mn_sensor_als_als1_ag_ll | mn_sensor_als_als0_ag_ll | mn_sensor_als_als_acycle_ll;
    mn_sensor_I2C_Write_Block( DEVREG_ALS_AG_CFG_LL, buf_block, 2);
    set_ag_threshold( DEVREG_ALS_AG_L2LL_THL, mn_sensor_als_als_ag_l2ll_thd);
    set_ag_threshold( DEVREG_ALS_AG_LL2L_THL, mn_sensor_als_als_ag_ll2l_thd);
  }
  //set mode and wait
  //ret = mn_sensor_I2C_Write( DEVREG_ENABLE, (mn_sensor_wait | mn_sensor_mode) );
  //Serial.printf( "[mn_write_global_variable] - ret=%d \n", ret);
  return ret;
}
void initial_global_variable(void)
{
  //general setting
  alsps_oled_flag = false;
  alsps_TJC_flag = false;
  mn78xxx_dev_ps_enable = true;
  mn78xxx_dev_als_enable = true;
  als_timer_report_flag = false;//轮询时标志位，如果是true怎读一次数据
  ps_timer_report_flag = false;
  mn_sensor_wait = MN_WAIT_2_MS;
  mn_sensor_mode = MN_MODE_IDLE;
  mn_sensor_wait_clk = WAIT_CLK_1M_EN;
  mn_sensor_interrupt_control = MN_INT_CTRL_ALS_OR_PS;
  mn_sensor_als_dk_period_en = DARK_FRMAE_EN;
  mn_sensor_als_als_pixel_mode = ALS_PIXEL_HW;
  mn_sensor_als_dk_period = DARK_FRMAE_1_32768;
  mn_sensor_als_pixel_sel = PIXEL_IR0B_ALS_NODK; //PIXEL_IR0B_ALS_NODK; //PIXEL_IR0B_ALS;
  mn_sensor_als_cal_mode = MN_ALS_SUB_DK_DIS; //MN_ALS_SUB_DK_DIS; //MN_ALS_SUB_DK_EN;
  //mn_sensor_als_polling_mode = true; //mTask.polling_mode_als;
  mn_sensor_als_integration_time = MN_ALS_INTT_384;
  mn_sensor_als_als_gain0 = MN_GAIN0_LOW;
  mn_sensor_als_als_gain1 = MN_GAIN1_LOW;
  mn_sensor_als_cycle = MN_CYCLE_16;
  mn_sensor_als_report_type = CMC_BIT_PRE_COUNT; //CMC_BIT_RAW; //CMC_BIT_PRE_COUNT
  mn_sensor_als_factory_lux_per_count = 300; //1
  mn_sensor_als_als_ag_en = MN_AG_EN;
  mn_sensor_als_als0_ag_h =  (MN_GAIN0_MID << 4);
  mn_sensor_als_als0_ag_m =  (MN_GAIN0_LOW << 4);
  mn_sensor_als_als0_ag_l =  (MN_GAIN0_LOW << 4);
  mn_sensor_als_als1_ag_h =  (MN_GAIN1_HIGH << 4);
  mn_sensor_als_als1_ag_m =  (MN_GAIN1_MID << 4);
  mn_sensor_als_als1_ag_l =  (MN_GAIN1_LOW << 4);
  mn_sensor_als_als_aintt_h = (MN_ALS_INTT_1536 >> 4);
  mn_sensor_als_als_aintt_m = (MN_ALS_INTT_768 >> 4);
  mn_sensor_als_als_aintt_l = (MN_ALS_INTT_192 >> 4);
  mn_sensor_als_als_aenh_h = (MN_ALS_ENH_MODE_1 << 4);
  mn_sensor_als_als_aenh_m = (MN_ALS_ENH_MODE_1 << 4);
  mn_sensor_als_als_aenh_l = (MN_ALS_ENH_MODE_1 << 4);
  mn_sensor_als_als_acycle_h = MN_CYCLE_32;
  mn_sensor_als_als_acycle_m = MN_CYCLE_64;
  mn_sensor_als_als_acycle_l = MN_CYCLE_256;

  mn_sensor_als_als_ag_h2m_thd = 60000;
  mn_sensor_als_als_ag_m2h_thd = 5000;
  mn_sensor_als_als_ag_m2l_thd = 60000;
  mn_sensor_als_als_ag_l2m_thd = 1500;
  //  mn_sensor_als_factory_lux_per_lux = 1000; //1, mn_sensor_als_cali()
  mn_sensor_als_persist = MN_PERIST_1;
  mn_sensor_als_enh_mode = MN_ALS_ENH_MODE_1;
  mn_sensor_als_ma_en = MN_ALS_MA_EN;
  mn_sensor_als_als_rs = MN_RS_0;
  mn_sensor_als_als_std = MN_ALS_PRE;
  mn_sensor_als_interrupt_channel_select = MN_ALS_INT_CHSEL_1;
  mn_sensor_als_als_offset = 0;
  mn_sensor_als_als_ag_ch0sat_en = MN_AG_CH0_SAT_EN;

  if (mn_sensor_als_polling_mode)
    mn_sensor_als_interrupt_type = MN_INTTY_DISABLE;
  else
  {
    mn_sensor_als_interrupt_type = MN_INTTY_ACTIVE;
    mn_sensor_als_als_intr_percent = 20;
  }
  mn_sensor_als_als_ag_ch0sat_en = MN_AG_CH0_SAT_EN;
  mn_sensor_als_als_ag_nor_h2m_thd = mn_sensor_als_als_ag_h2m_thd / mn78_sensor_als_ag_calc_new_thd( mn_sensor_als_als_aintt_h, mn_sensor_als_als_aenh_h, mn_sensor_als_als1_ag_h );
  mn_sensor_als_als_ag_nor_m2l_thd = mn_sensor_als_als_ag_m2l_thd / mn78_sensor_als_ag_calc_new_thd( mn_sensor_als_als_aintt_m, mn_sensor_als_als_aenh_m, mn_sensor_als_als1_ag_m );
  mn_sensor_als_als_ag_nor_l2m_thd = mn_sensor_als_als_ag_l2m_thd / mn78_sensor_als_ag_calc_new_thd( mn_sensor_als_als_aintt_l, mn_sensor_als_als_aenh_l, mn_sensor_als_als1_ag_l );
  mn_sensor_als_als_ag_nor_m2h_thd = mn_sensor_als_als_ag_m2h_thd / mn78_sensor_als_ag_calc_new_thd( mn_sensor_als_als_aintt_m, mn_sensor_als_als_aenh_m, mn_sensor_als_als1_ag_m );
  //Serial.printf("[initial_global_variable]: AG_THD: H2M=%d, M2L=%d, L2M=%d, M2H=%d \r\n", mn_sensor_als_als_ag_nor_h2m_thd, mn_sensor_als_als_ag_nor_m2l_thd, mn_sensor_als_als_ag_nor_l2m_thd, mn_sensor_als_als_ag_nor_m2h_thd);
  //if als_ag_3stage is enabled, ignore it
  mn_sensor_als_als_ag_3stage = MN_AG_3STG_DIS; //MN_AG_3STG_DIS//MN_AG_3STG_EN
  mn_sensor_als_als_aintt_ll = (MN_ALS_INTT_48 >> 4);
  mn_sensor_als_als_acycle_ll = MN_CYCLE_256;
  mn_sensor_als_als0_ag_ll = (MN_GAIN0_LOW << 4);
  mn_sensor_als_als1_ag_ll = (MN_GAIN1_LOW << 4);
  mn_sensor_als_als_ag_l2ll_thd = 30000;
  mn_sensor_als_als_ag_ll2l_thd = 400;
  if (mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
  {
    int intt_value = 0, gain_value = 0;

    intt_value =  (1 << (mn_sensor_als_als_aintt_l - mn_sensor_als_als_aintt_ll) / 2);

    if ( (mn_sensor_als_als1_ag_ll >> 4) == MN_GAIN1_HH )
      gain_value = 64;
    else if ( (mn_sensor_als_als1_ag_ll >> 4) == MN_GAIN1_HIGH )
      gain_value = 32;
    else if ( (mn_sensor_als_als1_ag_ll >> 4) == MN_GAIN1_MID )
      gain_value = 8;
    else
      gain_value = 1;

    if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_HH )
      gain_value /= 64;
    else if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_HIGH )
      gain_value /= 32;
    else if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_MID )
      gain_value /= 8;
    mn_sensor_als_ag_ll_lpc_gain = intt_value * gain_value;
    mn_sensor_als_ag_ll_lpc_gain = 4;//手动设置
    Serial.printf("[initial_global_variable]: intt_value=%u ,gain_value=%u ,mn_sensor_als_als_aintt_l=%u, mn_sensor_als_als_aintt_ll=%u \n", intt_value , gain_value, mn_sensor_als_als_aintt_l, mn_sensor_als_als_aintt_ll);
    //Serial.printf("[initial_global_variable]: lpc_gain=%u \n", mn_sensor_als_ag_ll_lpc_gain);
  }
  //ALS_LSRC
  mn_sensor_als_low_threshold = 2000;
  mn_sensor_als_high_threshold = 5000;
  mn_sensor_als_offset_gain = 500;
  mn_sensor_als_scale_gain = 1000;
  mn_sensor_als_factory_lux_per_lux = 1000;
  //ps setting
  //mn_sensor_ps_polling_mode = true;
  mn_sensor_ps_enh_mode = MN_PS_ENH_MODE_1;
  mn_sensor_ps_ps_std = MN_PS_PRE;
  mn_sensor_ps_interrupt_channel_select = MN_PS0_INT_CHSEL;
  mn_sensor_ps_ir_on_control = MN_IR_ON_CTRL_ON;
  mn_sensor_ps_ps_offset = 0;
  if (mn_sensor_ps_polling_mode == true)
    mn_sensor_ps_interrupt_type = MN_INTTY_DISABLE;
  else
    mn_sensor_ps_interrupt_type = MN_INTTY_ACTIVE;
  mn_sensor_ps_ps_ir0b23_sel = PS_IR_CTIA0;
  mn_sensor_ps_ps_ir3_en = PS_IR3_EN;
  mn_sensor_ps_ps_ir2_en = PS_IR2_EN;
  mn_sensor_ps_ps_ir1_en = PS_IR1_DIS;
  mn_sensor_ps_ps_ir0b_en = PS_IR0B_EN;
  mn_sensor_ps_ps_ir0a_en = PS_IR0A_DIS;

  mn_sensor_ps_integration_time = MN_PS_INTT_80;
  mn_sensor_ps_ps_gain0 = MN_GAIN0_MID;
  mn_sensor_ps_ps_gain1 = MN_GAIN1_MID;
  mn_sensor_ps_ps_pulse = MN_PS_PULSE_16; //match ps_avg
  mn_sensor_ps_ps_avg = MN_AVG_64;
  mn_sensor_ps_persist = MN_PERIST_1;
  mn_sensor_ps_ir_drive = MN_IR_DRIVE_50;
  mn_sensor_ps_ir_drive_tune = MN_IR_DRIVE_14_92;
  mn_sensor_ps_ps_max_ct = 10000; //enable PS
  mn_sensor_ps_low_threshold = 2000;
  mn_sensor_ps_high_threshold = 5000;
  mn_sensor_ps_dynk_min_ps_raw_data = 65535;
  mn_sensor_ps_dynk_max_ir_data = 40000;
  mn_sensor_ps_dynk_low_offset = 500;
  mn_sensor_ps_dynk_high_offset = 2500;
#if PS_GREASE
  ps_grease_thd = mn_sensor_ps_ps_max_ct;
  ps_grease_add = 100;
#endif
  /**************************************************************************************
    #
  ****************************************************************************************/
  mn78_write_global_variable();
  mn_sensor_I2C_Write(DEVREG_RESET, (MN_POWER_OFF | MN_RESETN_RESET));//sleep
  mn_sensor_update_mode();
  // mn_sensor_I2C_Write(DEVREG_ENABLE, (MN_WAIT_2_MS | MN_MODE_ALS_PS));//MODE, Wait=2ms
  mn_sensor_I2C_Write(DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN));//WAKEUP
}

uint16_t set_psensor_intr_threshold(uint16_t ailt, uint16_t aiht)
{
  int ret = 0;
  uint8_t thd[4];

  thd[0] = (uint8_t) (ailt & 0x00ff);
  thd[1] = (uint8_t) (ailt >> 8);
  thd[2] = (uint8_t) (aiht & 0x00ff);
  thd[3] = (uint8_t) (aiht >> 8);
  ret = mn_sensor_I2C_Write_Block(DEVREG_PS_ILTL, thd, 4);
  Serial.printf("[%s]:  ret=%d, low_thd = %d, high_thd = %d \n", __func__,  ret, ailt, aiht);
  return ret;
}
int set_lsensor_intr_threshold(uint16_t ailt, uint16_t aiht)
{
  int ret = 0;
  uint8_t thd[4];

  thd[0] = (uint8_t) (ailt & 0x00ff);
  thd[1] = (uint8_t) (ailt >> 8);
  thd[2] = (uint8_t) (aiht & 0x00ff);
  thd[3] = (uint8_t) (aiht >> 8);
  ret = mn_sensor_I2C_Write_Block(DEVREG_ALS_ILTL, thd, 4);
  //Serial.printf("[%s]: ret=%d, low_thd = %d, high_thd = %d \n", __func__,  ret, ailt, aiht);
  return ret;
}
int set_ag_threshold(uint16_t reg_addr, uint16_t ag_thd)
{
  int ret = -1;
  uint8_t thd[2];

  thd[0] = (uint8_t) (ag_thd & 0x00ff);
  thd[1] = (uint8_t) (ag_thd >> 8);
  ret = mn_sensor_I2C_Write_Block(reg_addr, thd, 2);
  //Serial.printf("[set_ag_threshold] - ret=%d, REG0x%x: ag_thd=%d \n", ret, reg_addr, ag_thd);
  //Serial.printf("[set_ag_threshold] - thd[0]=%x thd[1]=%x \n",  thd[0], thd[1]);
  return ret;
}
static int select_pixel_scale()
{
  int ret = -1;
  uint8_t pxl_scale[2];
  if ( (mn_sensor_als_pixel_sel == PIXEL_IR0A0B_ALS) || (mn_sensor_als_pixel_sel == PIXEL_CLR_ALS) )
  { //ch0:4x, ch1:2x
    pxl_scale[0] = 0x01;
    pxl_scale[1] = 0x8A;
  }
  else if (mn_sensor_als_pixel_sel == PIXEL_IR0A0B_CLR)
  { //ch0:4x, ch1:4x, 0_8725
    pxl_scale[0] = 0x05;
    pxl_scale[1] = 0xAA;
  }
  else if (mn_sensor_als_pixel_sel == PIXEL_IR0A0B_ALS_CLR)
  { //ch0:4x, ch1:4x, 1_375
    pxl_scale[0] = 0x05;
    pxl_scale[1] = 0x6A;
  }
  else
  {
    pxl_scale[0] = 0x00;
    pxl_scale[1] = 0x8A;
  }
  ret = mn_sensor_I2C_Write_Block(0x14, pxl_scale, 2);
  //Serial.printf("[select_pixel_scale] - scale=0x%x, factor=0x%x \r\n", pxl_scale[0], pxl_scale[1]);
  return ret;
}
static uint16_t mn78_sensor_als_ag_calc_new_thd(uint16_t intt, uint16_t enh, uint16_t gain)
{
  int intt_value = 0, gain_value = 0, enh_shift, gain_shift, total_value = 0;
  enh_shift = (enh >> 4);
  gain_shift = (gain >> 4);

  if (gain_shift == MN_GAIN1_HH)
    gain_value = 64;
  else if (gain_shift == MN_GAIN1_HIGH)
    gain_value = 32;
  else if (gain_shift == MN_GAIN1_MID)
    gain_value = 8;
  else
    gain_value = 1;

  if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_HH)
    gain_value /= 64;
  else if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_HIGH)
    gain_value /= 32;
  else if ( (mn_sensor_als_als1_ag_l >> 4) == MN_GAIN1_MID)
    gain_value /= 8;

  intt_value = ( (1 << (intt - mn_sensor_als_als_aintt_l) / 2) << enh_shift );

  total_value = intt_value * gain_value;
  ////Serial.printf("[mn78_sensor_als_ag_calc_new_thd]: intt_value=%d, total_value=%d \r\n", intt_value, total_value);

  return total_value;
}
static void mn_sensor_als_ag_fast_update(bool fast_flag)
{
  uint8_t buf_block[6];
  //Serial.printf("mn_sensor_als_ag_fast_update(%d)\r\n", fast_flag);
  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_OFF | MN_RESETN_RESET) );
  if (fast_flag)
  {
    if (mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
      mn_sensor_I2C_Write( DEVREG_ALS_AG_FILT_LL, (mn_sensor_als_als1_ag_ll | mn_sensor_als_als0_ag_ll | MN_CYCLE_1));
    buf_block[0] = mn_sensor_als_als_aenh_l | mn_sensor_als_als_aintt_l;
    buf_block[1] = mn_sensor_als_als1_ag_l | mn_sensor_als_als0_ag_l | MN_CYCLE_1;
    buf_block[2] = mn_sensor_als_als_aenh_m | mn_sensor_als_als_aintt_m;
    buf_block[3] = mn_sensor_als_als1_ag_m | mn_sensor_als_als0_ag_m | MN_CYCLE_1;
    buf_block[4] = mn_sensor_als_als_aenh_h | mn_sensor_als_als_aintt_h;
    buf_block[5] = mn_sensor_als_als1_ag_h | mn_sensor_als_als0_ag_h | MN_CYCLE_1;
    mn_sensor_I2C_Write_Block( DEVREG_ALS_AG_CFG_L, buf_block, 6);
  }
  else
  {
    if (mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
      mn_sensor_I2C_Write( DEVREG_ALS_AG_FILT_LL, (mn_sensor_als_als1_ag_ll | mn_sensor_als_als0_ag_ll | mn_sensor_als_als_acycle_ll));
    buf_block[0] = mn_sensor_als_als_aenh_l | mn_sensor_als_als_aintt_l;
    buf_block[1] = mn_sensor_als_als1_ag_l | mn_sensor_als_als0_ag_l | mn_sensor_als_als_acycle_l;
    buf_block[2] = mn_sensor_als_als_aenh_m | mn_sensor_als_als_aintt_m;
    buf_block[3] = mn_sensor_als_als1_ag_m | mn_sensor_als_als0_ag_m | mn_sensor_als_als_acycle_m;
    buf_block[4] = mn_sensor_als_als_aenh_h | mn_sensor_als_als_aintt_h;
    buf_block[5] = mn_sensor_als_als1_ag_h | mn_sensor_als_als0_ag_h | mn_sensor_als_als_acycle_h;
    mn_sensor_I2C_Write_Block( DEVREG_ALS_AG_CFG_L, buf_block, 6);
  }
  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN) );
}



static bool mn78_sensor_ag_stage_change(uint16_t ch1)
{
  bool ret = false;
  if (ch1 == mn_sensor_als_als_ag_nor_h2m_thd ||
      ch1 == mn_sensor_als_als_ag_nor_m2h_thd ||
      ch1 == mn_sensor_als_als_ag_nor_m2l_thd ||
      ch1 == mn_sensor_als_als_ag_nor_l2m_thd)
  {
    ret = true;
  }
  if ( (mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
       && (ch1 == mn_sensor_als_als_ag_l2ll_thd || ch1 == mn_sensor_als_als_ag_ll2l_thd) )
  {
    ret = true;
  }
  return ret;
}
static void mn_sensor_update_mode(void)
{
  bool enable_ps = mn78xxx_dev_ps_enable;
  bool enable_als = mn78xxx_dev_als_enable;

  //Serial.printf("mode selection =0x%x\n", enable_ps | (enable_als << 1));
  switch ((enable_als << 1) | enable_ps)
  {
    case 0: //disable all
      mn_sensor_mode = MN_MODE_IDLE;
      break;
    case 1: //als = 0, ps = 1
      mn_sensor_mode = MN_MODE_PS;
      break;
    case 2: //als = 1, ps = 0
      mn_sensor_mode = MN_MODE_ALS;
      break;
    case 3: //als = 1, ps = 1
      mn_sensor_mode = MN_MODE_ALS_PS;
      break;
  }
  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_OFF | MN_RESETN_RESET) );
  mn_sensor_I2C_Write( DEVREG_ENABLE, (mn_sensor_wait | mn_sensor_mode) );
  mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN) );
}
static int mn78_sensor_enable_ps(bool enable)
{
  int ret = -1;
  //Serial.printf("[mn_sensor_enable_ps]: ps enable=%d \n", enable);

  if (enable)
  {
    mn78xxx_dev_ps_enable = true;
    ps_first_flag = true;
    set_psensor_intr_threshold(mn_sensor_ps_ps_max_ct, (mn_sensor_ps_ps_max_ct + 1));
    mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN) );
    mn_sensor_I2C_Write( DEVREG_PS_STATUS, (MN_CMP_RESET | MN_LOCK) );
    mn_sensor_I2C_Write( DEVREG_PS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );
#if PS_DYN_K
    mn_sensor_ps_dynk_min_ps_raw_data = 0xffff;
#endif
  }
  else
  {
    mn78xxx_dev_ps_enable = false;
    ps_first_flag = false;
  }
  mn_sensor_update_mode();
  return ret;
}
static int mn78_sensor_enable_als( bool enable)
{
  int ret = -1;
  //Serial.printf("[mn_sensor_enable_als]: als enable=%d \n", enable);

  if (enable)
  {
    mn78xxx_dev_als_enable = true;
    als_first_flag = true;
    set_lsensor_intr_threshold( L_SENSOR_LTHD_TRIGER, L_SENSOR_HTHD );
    mn_sensor_I2C_Write( DEVREG_RESET, (MN_POWER_ON | MN_RESETN_RUN) );
    mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RESET | MN_LOCK) );
    mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );
    if (mn_sensor_als_als_ag_en == MN_AG_EN)
    {
      mn_sensor_als_ag_last_stage = MN_AG_STAGE_LL;
      mn_sensor_als_ag_fast_update(true);
    }

  }
  else
  {
    mn78xxx_dev_als_enable = false;
    als_first_flag = false;
  }
  mn_sensor_update_mode();
  return ret;
}
static void lsrc_raw_convert_to_adc(uint32_t ch0, uint32_t ch1, uint16_t *new_raw)
{
  uint32_t als_offset = 0, als_scale = 0;
  uint16_t nor_raw = 0;
  //Serial.printf("[lsrc_raw_convert_to_adc]: als_offset=%lu , als_scale=%lu \r\n", mn_sensor_als_offset_gain, mn_sensor_als_scale_gain);
  if (ch1 > 0)
  {
    lsrc_ratio = ch0 * 1000 / ch1;
    als_offset = (ch0 * ch0) / (ch0 + ch1) * mn_sensor_als_offset_gain / 1000;
    als_scale = (1000 - mn_sensor_als_scale_gain) * ch1 / 1000;
    //Serial.printf("[lsrc_raw_convert_to_adc]: als_offset=%lu , als_scale=%lu \r\n", als_offset, als_scale);
    if ( als_offset < als_scale )
      nor_raw = ch1 - als_offset;
    else
      nor_raw = ch1 * mn_sensor_als_scale_gain / 1000;
  }
  else
  {
    nor_raw = ch1;
  }
  *new_raw = nor_raw;
  //Serial.printf("[lsrc_raw_convert_to_adc]: ch0=%lu, ch1=%lu, nor_raw=%u \r\n", ch0, ch1, nor_raw);
}
void lux_convert_to_lux(uint32_t raw, uint32_t lpc, uint32_t *new_lux)
{
  uint32_t lux = 0, new_lpc;

  new_lpc = mn_sensor_als_factory_lux_per_lux * lpc / 1000;
  lux =  new_lpc * raw;
  *new_lux = lux;
 // Serial.printf("[lux_convert_to_lux]: lux_per_lux=%d, new_lpc=%lu, lux=%lu \n", mn_sensor_als_factory_lux_per_lux, new_lpc, lux / 1000);
}
static bool mn78_sensor_ag_4stage_lpc(uint32_t *new_lpc)
{

  //Serial.printf("[mn78_sensor_ag_4stage_lpc]: mn_sensor_als_ag_last_stage=0x%x \r\n", mn_sensor_als_ag_last_stage);

  if ( (als_first_flag == false) && (mn_sensor_als_ag_last_stage == MN_AG_STAGE_LL) && (mn_sensor_als_ag_last_stage != mn_sensor_als_ag_current_stage) && (mn_sensor_als_data_channel1 == mn_sensor_als_als_ag_ll2l_thd) ) //LLtoL
  {
    *new_lpc = mn_sensor_als_factory_lux_per_count * mn_sensor_als_ag_ll_lpc_gain;
  }
  else if ( (mn_sensor_als_ag_current_stage == MN_AG_STAGE_LL) && (mn_sensor_als_ag_last_stage != mn_sensor_als_ag_current_stage) && (mn_sensor_als_data_channel1 == mn_sensor_als_als_ag_l2ll_thd) ) //LtoLL
  {
    *new_lpc = mn_sensor_als_factory_lux_per_count;
  }
  else if ( (mn_sensor_als_ag_current_stage == MN_AG_STAGE_LL) && (mn_sensor_als_ag_last_stage != mn_sensor_als_ag_current_stage) && (mn_sensor_als_als_sat & 0x11) ) //LtoLL, ch0_sat
  {
    mn_sensor_als_ag_last_stage = mn_sensor_als_ag_current_stage;
    return false;
  }
  else if (mn_sensor_als_ag_current_stage  == MN_AG_STAGE_LL) //LL_stage
  {
    *new_lpc = mn_sensor_als_factory_lux_per_count * mn_sensor_als_ag_ll_lpc_gain;
    if (mn_sensor_als_data_channel1 == mn_sensor_als_als_ag_l2ll_thd)
    {
      mn_sensor_als_ag_last_stage = mn_sensor_als_ag_current_stage;
      return false;
    }
  }
  else
  {
    *new_lpc = mn_sensor_als_factory_lux_per_count;
    if (mn_sensor_als_data_channel1 == mn_sensor_als_als_ag_ll2l_thd)
    {
      mn_sensor_als_ag_last_stage = mn_sensor_als_ag_current_stage;
      return false;
    }
  }
  mn_sensor_als_ag_last_stage = mn_sensor_als_ag_current_stage;
 // Serial.printf("[mn78_sensor_ag_4stage_lpc]: new_lpc=%lu, ch1=%d ,mn_sensor_als_ag_ll_lpc_gain=%d \r\n", *new_lpc, mn_sensor_als_data_channel1, mn_sensor_als_ag_ll_lpc_gain);
  return true;
}

static uint16_t mn_sensor_get_als_value(uint16_t als_ch0, uint16_t als_ch1)
{
  uint32_t lux, als_new_lpc = 0;
  uint16_t als_lsrc_raw = 0;

  switch (mn_sensor_als_report_type)
  {
    case CMC_BIT_RAW:
      return als_ch1;
      break;
    case CMC_BIT_PRE_COUNT:
      lsrc_raw_convert_to_adc(als_ch0, als_ch1, &als_lsrc_raw);
      if (mn_sensor_als_als_ag_en == MN_AG_EN && mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS) //LL_stage
      {
        if ( mn78_sensor_ag_4stage_lpc(&als_new_lpc) ==  false)
        {
          //Serial.printf("mn_sensor_get_als_value=lux=%lu \r\n", mn_sensor_als_data_lux);
          return mn_sensor_als_data_lux;
        }
      }
      else
        als_new_lpc = mn_sensor_als_factory_lux_per_count;
      lsrc_lux = als_new_lpc * als_lsrc_raw / 1000;
      lux_convert_to_lux(als_lsrc_raw, als_new_lpc, &lux);
      return (lux / 1000);
      break;
  }
  return 0;
}
static int32_t mn78xxx_read_als()
{
  int ret = 0;
  uint8_t rx_buf[8] = {0};

  ret = mn_sensor_I2C_Read(DEVREG_ALS_STATUS, i2cData, 8);
  mn_sensor_als_compare_high = (i2cData[0] & 0x10);
  mn_sensor_als_compare_low = (i2cData[0] & 0x08);
  mn_sensor_als_interrupt_flag = (i2cData[0] & 0x04);
  mn_sensor_als_compare_reset = (i2cData[0] & 0x02);
  mn_sensor_als_lock = (i2cData[0] & 0x01);
  mn_sensor_als_status = i2cData[0];
  mn_sensor_als_als_sat = i2cData[1];
  mn_sensor_als_data_channel0 = ((i2cData[3] << 8) | i2cData[2]);
  mn_sensor_als_data_channel1 = ((i2cData[5] << 8) | i2cData[4]);
  mn_sensor_als_data_channel2 = ((i2cData[7] << 8) | i2cData[6]);

  //Serial.printf("[mn78xxx_read_als]: als_status = 0x%x, als_sat = 0x%x\n", mn_sensor_als_status, mn_sensor_als_als_sat);
  //Serial.printf("[mn78xxx_read_als]: ch0=%d, ch1=%d, ch2=%d \n", mn_sensor_als_data_channel0, mn_sensor_als_data_channel1, mn_sensor_als_data_channel2);
  if (mn_sensor_als_als_ag_en == MN_AG_EN)
  {
    mn_sensor_I2C_Read(DEVREG_ALS_AG_STAGE, i2cData, 1);
    mn_sensor_als_ag_current_stage = ((i2cData[0] & 0x30) >> 4);
    //Serial.printf("[mn78xxx_read_als]: ag_current_stage = 0x%x\n", mn_sensor_als_ag_current_stage);
  }

  if (mn_sensor_als_polling_mode == true)
  {
    if (mn_sensor_als_compare_high == mn_sensor_als_compare_low)
    {
      //Serial.printf("[mn78xxx_read_als]: als don't ready \r\n");
      return -1;
    }
    if (als_first_flag == true && (mn_sensor_als_als_ag_en == MN_AG_EN) && mn78_sensor_ag_stage_change(mn_sensor_als_data_channel1) )
    {
      //Serial.printf("[mn_sensor_read_als]: als_ag don't ready \r\n");
      return -1;
    }

  }

  return mn_sensor_als_data_channel1;
}
#if PS_DYN_K //PS_DYN_K+
static void mn78_sensor_do_ps_auto_k(void)
{
  Serial.printf("[mn78_sensor_do_ps_auto_k]:dynk_min_ps_raw_data = %d \n", mn_sensor_ps_dynk_min_ps_raw_data);

  if ( (mn_sensor_ps_dynk_min_ps_raw_data > mn_sensor_ps_data_pdata)
       && (mn_sensor_ps_data_pdata < mn_sensor_ps_ps_max_ct)
       && (mn_sensor_ps_compare_low)
       && (mn_sensor_ps_sat == 0)
       && (mn_sensor_ps_data_ir_data < mn_sensor_ps_dynk_max_ir_data) )
  {
    mn_sensor_ps_dynk_min_ps_raw_data = mn_sensor_ps_data_pdata;
    dynk_thd_low = mn_sensor_ps_dynk_min_ps_raw_data + mn_sensor_ps_dynk_low_offset;
    dynk_thd_high = mn_sensor_ps_dynk_min_ps_raw_data + mn_sensor_ps_dynk_high_offset;

    if (dynk_thd_low > 65534)
      dynk_thd_low = 65534;
    if (dynk_thd_high > 65535)
      dynk_thd_high = 65535;

    set_psensor_intr_threshold(dynk_thd_low, dynk_thd_high);
    mn_sensor_read_ps_thd();
    Serial.printf("[mn78_sensor_do_ps_auto_k]: dyn ps raw = %d, min = %d, ir_data = %d\n", mn_sensor_ps_data_pdata, mn_sensor_ps_dynk_min_ps_raw_data, mn_sensor_ps_data_ir_data);
  }
}
#endif //PS_DYN_K-

static int32_t mn78xxx_read_ps()
{
  int ret = 0;
  //uint8_t rx_buf[11] = {0};
  ret = mn_sensor_I2C_Read(DEVREG_PS_STATUS, i2cData, 11);

  mn_sensor_ps_compare_high = (i2cData[0] & 0x10);
  mn_sensor_ps_compare_low = (i2cData[0] & 0x08);
  mn_sensor_ps_interrupt_flag = (i2cData[0] & 0x04);
  mn_sensor_ps_compare_reset = (i2cData[0] & 0x02);
  mn_sensor_ps_lock = (i2cData[0] & 0x01);
  mn_sensor_ps_status = i2cData[0];
  mn_sensor_ps_ps0_sat = i2cData[1];
  mn_sensor_ps_ps1_sat = i2cData[2];
  mn_sensor_ps_data_ps0_channel0 = (uint16_t)((i2cData[4] << 8) | i2cData[3]);
  mn_sensor_ps_data_ps0_channel1 = (uint16_t)((i2cData[6] << 8) | i2cData[5]);
  mn_sensor_ps_data_ps1_channel0 = (uint16_t)((i2cData[8] << 8) | i2cData[7]);
  mn_sensor_ps_data_ps1_channel1 = (uint16_t)((i2cData[10] << 8) | i2cData[9]);

  if (mn_sensor_ps_interrupt_channel_select == MN_PS0_INT_CHSEL)
  {
    mn_sensor_ps_sat = mn_sensor_ps_ps0_sat;
    mn_sensor_ps_data_ir_data = mn_sensor_ps_data_ps0_channel0;
    mn_sensor_ps_data_pdata = mn_sensor_ps_data_ps0_channel1;
  }
  else
  {
    mn_sensor_ps_sat = mn_sensor_ps_ps1_sat;
    mn_sensor_ps_data_ir_data = mn_sensor_ps_data_ps1_channel0;
    mn_sensor_ps_data_pdata = mn_sensor_ps_data_ps1_channel1;
  }
  //Serial.printf("[mn78_sensor_read_ps]: chsel = 0x%x, ps_status=0x%x, ps_sat=0x%x \n", (mn_sensor_ps_interrupt_channel_select >> 7), mn_sensor_ps_status, mn_sensor_ps_sat);
  //Serial.printf("[mn78_sensor_read_ps]: irdata=%d, pdata=%d \n" , mn_sensor_ps_data_ir_data, mn_sensor_ps_data_pdata);

  return mn_sensor_ps_data_pdata;
}
static void mn78_sensor_report_ps(uint8_t ps_state)
{
#if (PS_DYN_K && !PS_DYN_K_TIMER)
  mn78_sensor_do_ps_auto_k();
#endif //PS_DYN_K-
  //  mTask.data.sensType = SENS_TYPE_PROX;
  if ( ps_state == 1 )
  { /* 1 is far */
    //mTask.data.prox_state = PROX_STATE_FAR; /* far */
    mTask_data_prox_data = 1; /* far state distance is 1cm */
  }
  else
  {
    //mTask_data_prox_state = PROX_STATE_NEAR; /* near */
    mTask_data_prox_data = 0; /* near state distance is 0cm */
  }
  Serial.printf("[%s]: =====> prox_state=%d, pdata:%d\n", __func__, mTask_data_prox_data, mn_sensor_ps_data_pdata);
}
static void mn78_sensor_report_als()
{
  if (mn_sensor_als_compare_high == mn_sensor_als_compare_low)
  {
    //Serial.printf("[report_als]: als don't ready \r\n");
    return;
  }

  if (als_first_flag == true && (mn_sensor_als_als_ag_en == MN_AG_EN) && mn78_sensor_ag_stage_change(mn_sensor_als_data_channel1) )
  {
    //Serial.printf("[report_als]: als_ag don't ready \r\n");
    return;
  }
  // mn78xxx_dev_als_last_sample = lux;
  //mTask_data_sensType = SENS_TYPE_ALS;
  mTask_data_als_data = mn_sensor_get_als_value(mn_sensor_als_data_channel0, mn_sensor_als_data_channel1);
  Serial.printf("[%s]: =====> Lux=%lu,ch0: %d, ch1:%d\n", __func__, mTask_data_als_data, mn_sensor_als_data_channel0, mn_sensor_als_data_channel1);

  if (als_first_flag)
    mn_sensor_als_ag_fast_update(false);
  als_first_flag = false;

  mn_sensor_als_data_lux = mTask_data_als_data;
}
static int mn78xxx_als_enable()
{
  int ret = 0;
  ret = mn78_sensor_enable_als(true);

  //mn78xxx_dev.als_debounce_on = 1;
  //cal_end_time(mn78xxx_dev.als_debounce_time, &mn78xxx_dev.als_debounce_end);

  return 0;
}

static int mn78xxx_als_disable()
{
  int ret = 0;
  //mn78xxx_dev.als_debounce_on = 0;

  ret = mn78_sensor_enable_als(false);

  //rt_timer_stop(&mn78xxx_dev.timer[ALS]);
  return 0;
}
static int mn78xxx_als_sample()
{

  if (als_timer_report_flag == true)
  {
    als_timer_report_flag = false;
    mn_sensor_read_als_ag_thd_data();
    mn78xxx_read_als();
    mn78_sensor_report_als();
  }
  return 0;
}

static int mn78xxx_ps_enable()
{
  int ret = 0;

  //Serial.printf("mn78xxx_ps_power_on\n");

  //mn78xxx_dev_ps_last_sample = PROX_STATE_INIT;

  ret = mn78_sensor_enable_ps(true);

  return 0;
}

static int mn78xxx_ps_disable()
{
  int ret = 0;

  // rt_timer_stop(&mn78xxx_dev.timer[PS]);

  ret = mn78_sensor_enable_ps(false);

  return 0;
}

static int mn78xxx_ps_sample()
{
  //struct data_param *recv = (struct data_param*)data;
  if (ps_timer_report_flag == true)
  {
    uint8_t ps_status;
    ps_timer_report_flag = false;
    mn78xxx_read_ps();
    mn_sensor_read_ps_thd();
    ps_status = (mn_sensor_ps_compare_low >> 3);
    mn78_sensor_report_ps(ps_status);
  }
#if BLINKER
  //Blinker.run();
#endif
  return 0;
}

static void mn78_sensor_intr_als_set_thd(uint16_t raw)
{
  uint16_t thd_offset = 0;
  //Serial.printf("[mn78_sensor_intr_als_set_thd]: raw=%d, mn78_als_intr_thd_percent=%d \n", raw, mn_sensor_als_als_intr_percent);

  thd_offset = raw * mn_sensor_als_als_intr_percent / 100;
  if (thd_offset <= 0)
    thd_offset = 1;
  //Serial.printf("[mn78_sensor_intr_als_set_thd]: thd_offset=%d \r\n", thd_offset );
  //set low threshold
  if (raw < thd_offset)   //overflow
    mn_sensor_als_low_threshold = 0;
  else
    mn_sensor_als_low_threshold = raw - thd_offset;

  //set high threshold
  if (raw > (0xffff - thd_offset)) //overflow
    mn_sensor_als_high_threshold = 0xffff;
  else
    mn_sensor_als_high_threshold = raw + thd_offset;
  //set new threshold
  set_lsensor_intr_threshold(mn_sensor_als_low_threshold, mn_sensor_als_high_threshold);
}

static void mn78_sensor_intr_als_report_lux()
{
  uint32_t lux;

  if (als_first_flag == true && mn_sensor_als_als_ag_en == MN_AG_EN && mn78_sensor_ag_stage_change(mn_sensor_als_data_channel1) )
  {
    //Serial.printf("[mn78_sensor_intr_als_report_lux]: als_ag don't ready \r\n");
    set_lsensor_intr_threshold( L_SENSOR_LTHD_TRIGER, L_SENSOR_HTHD );
    return;
  }
  else if ( (mn_sensor_als_als_ag_en == MN_AG_EN && mn_sensor_als_als_ag_3stage == MN_AG_3STG_DIS)
            && (mn_sensor_als_ag_last_stage != mn_sensor_als_ag_current_stage || mn78_sensor_ag_stage_change(mn_sensor_als_data_channel1)) )
  {
    set_lsensor_intr_threshold(L_SENSOR_LTHD_TRIGER, L_SENSOR_HTHD);
  }
  else
    mn78_sensor_intr_als_set_thd(mn_sensor_als_data_channel1);

  lux = (int32_t)mn_sensor_get_als_value(mn_sensor_als_data_channel0, mn_sensor_als_data_channel1); //calculate lux
  mn78xxx_dev_als_raw_data = (uint32_t)mn_sensor_als_data_channel1;
  mn78xxx_dev_als_factory_data = lsrc_lux;
  mn78_sensor_report_als();
}

/********************中断函数*******************/
static void mn78xxx_eint_handler()
{
  if (alsps_int_flag == true) {
    Serial.printf("[%s]: xxxxxxxxxxxxxxxxx als/ps(%d/%d) \n", __func__, mn78xxx_dev_als_enable, mn78xxx_dev_ps_enable);

    mn78xxx_read_ps();
    mn78xxx_read_als();

    alsps_int_flag = false;
    //Serial.printf("[%s]: xxxxxxxxxxxxxxxxx als/ps(%d) \n", __func__, alsps_int_flag);
    if (mn_sensor_ps_interrupt_flag == MN_INT_TRIGGER )
    {
      uint8_t ps_status;
      //mn_sensor_read_ps_thd();
      ps_status = (mn_sensor_ps_compare_low >> 3);
#if PS_GREASE
      if ( mn_grease_algr(ps_status) )
#endif
        mn78_sensor_report_ps(ps_status);
      //PS unlock interrupt pin and restart chip
      mn_sensor_I2C_Write(DEVREG_PS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );
    }
    if (mn_sensor_als_interrupt_flag == MN_INT_TRIGGER)
    {
      /* ALS Interrupt */
      mn78_sensor_intr_als_report_lux();
      mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RESET | MN_LOCK) );
      mn_sensor_I2C_Write( DEVREG_ALS_STATUS, (MN_CMP_RUN | MN_UN_LOCK) );
    }
    //mt_eint_unmask(mn78xxx_dev_hw->eint_num);
  }
}

//ICACHE_RAM_ATTR void mn78xxx_setup_eint()
void mn78xxx_setup_eint()
{
  alsps_int_flag = true;
}

/**************************************************************************************
  #define    DEVREG_INT_CTRL          0x01  8c    hh
****************************************************************************************/
static int mn_sensor_int_conf()
{
  int ret = -1;
  ret = mn_sensor_I2C_Write(DEVREG_INT_CTRL, (mn_sensor_als_als_ag_en | mn_sensor_interrupt_control | mn_sensor_wait_clk | mn_sensor_als_als_ag_ch0sat_en | mn_sensor_als_als_ag_3stage));
  return ret;
}
/**************************************************************************************
  #define    DEVREG_DARK_FRMAE        0x03  8f
  #define    DEVREG_ALS_PIXEL         0x04  1a   hh
  #define    DEVREG_PS_PIXEL          0x05  9a   hh
****************************************************************************************/
static int write_pxl_sel()
{
  int ret = -1;
  uint8_t buf[3];
  buf[0] = (mn_sensor_als_dk_period_en | mn_sensor_als_als_pixel_mode | mn_sensor_als_dk_period);
  buf[1] = mn_sensor_als_pixel_sel;
  buf[2] = (mn_sensor_ps_ps_ir0b23_sel | mn_sensor_ps_ps_ir3_en | mn_sensor_ps_ps_ir2_en | mn_sensor_ps_ps_ir1_en | mn_sensor_ps_ps_ir0b_en | mn_sensor_ps_ps_ir0a_en);
  ret = mn_sensor_I2C_Write_Block(DEVREG_DARK_FRMAE, buf, 3);
  return ret;
}
/**************************************************************************************
  #define    DEVREG_ALS_CONFIG        0x10   3f   hh
  #define    DEVREG_ALS_FILT          0x11   84   hh
  #define    DEVREG_ALS_INT           0x12   0    hh
  #define    DEVREG_ALS_ENH           0x13   0    04
****************************************************************************************/
static int write_als_conf()
{
  int ret = -1;
  uint8_t buf[4];
  buf[0] = mn_sensor_als_integration_time | mn_sensor_als_als_gain1 | mn_sensor_als_als_gain0;
  buf[1] = mn_sensor_als_interrupt_channel_select | mn_sensor_als_als_std | mn_sensor_als_cycle;
  buf[2] = mn_sensor_als_als_rs | mn_sensor_als_persist | mn_sensor_als_interrupt_type;
  buf[3] = mn_sensor_als_cal_mode | mn_sensor_als_enh_mode | 0x4;
  ret = mn_sensor_I2C_Write_Block(DEVREG_ALS_CONFIG, buf, 4);
  return ret;
}
/**************************************************************************************
  #define    0x14   0
             0x15   8a
****************************************************************************************/

/**************************************************************************************
  #define    DEVREG_PS_CONFIG         0x20   8a   hh
  #define    DEVREG_PS_PULSE          0x21   04   hh
  #define    DEVREG_PS_INT            0x22   60   hh
  #define    DEVREG_PS_ENH            0x23   0
  #define    DEVREG_LED_CONFIG        0x24   92   hh
****************************************************************************************/
static int write_ps_conf()
{
  int ret = -1;
  uint8_t buf[5];
  buf[0] = mn_sensor_ps_integration_time | mn_sensor_ps_ps_gain1 | mn_sensor_ps_ps_gain0;
  buf[1] = mn_sensor_ps_interrupt_channel_select | mn_sensor_ps_ps_std | mn_sensor_ps_ps_pulse;
  buf[2] = mn_sensor_ps_ps_avg | mn_sensor_ps_persist | mn_sensor_ps_interrupt_type;
  buf[3] = mn_sensor_ps_enh_mode;
  buf[4] = mn_sensor_ps_ir_on_control | mn_sensor_ps_ir_drive_tune | mn_sensor_ps_ir_drive;
  ret = mn_sensor_I2C_Write_Block(DEVREG_PS_CONFIG, buf, 5);
  return ret;
}
/**************************************************************************************
  #define    DEVREG_ALS_AG_CFG_L      0x52
  #define    DEVREG_ALS_AG_FILT_L     0x53
  #define    DEVREG_ALS_AG_CFG_M      0x54
  #define    DEVREG_ALS_AG_FILT_M     0x55
  #define    DEVREG_ALS_AG_CFG_H      0x56
  #define    DEVREG_ALS_AG_FILT_H     0x57
****************************************************************************************/
static int write_ag_conf()
{
  int ret = -1;
  uint8_t buf[6];
  buf[0] = mn_sensor_als_als_aenh_l | mn_sensor_als_als_aintt_l;
  buf[1] = mn_sensor_als_als1_ag_l | mn_sensor_als_als0_ag_l | mn_sensor_als_als_acycle_l;
  buf[2] = mn_sensor_als_als_aenh_m | mn_sensor_als_als_aintt_m;
  buf[3] = mn_sensor_als_als1_ag_m | mn_sensor_als_als0_ag_m | mn_sensor_als_als_acycle_m;
  buf[4] = mn_sensor_als_als_aenh_h | mn_sensor_als_als_aintt_h;
  buf[5] = mn_sensor_als_als1_ag_h | mn_sensor_als_als0_ag_h | mn_sensor_als_als_acycle_h;
  ret = mn_sensor_I2C_Write_Block(DEVREG_ALS_AG_CFG_L, buf, 6);
  return ret;
}

/**************************************************************************************

  中断函数
****************************************************************************************/


static int mn_sensor_read_als_ag_thd_data()
{
  int ret = -1;
  als_staust = i2cData[0];
  mn_sensor_I2C_Read(DEVREG_ALS_AG_H2M_THL, i2cData, 8);
  als_ag_h2m_thd = ((i2cData[1] << 8) | i2cData[0]);
  als_ag_m2h_thd = ((i2cData[3] << 8) | i2cData[2]);
  als_ag_m2l_thd = ((i2cData[5] << 8) | i2cData[4]);
  als_ag_l2m_thd = ((i2cData[7] << 8) | i2cData[6]);

  //Serial.printf("[%s]:h2m_thd = %d,m2h_thd=%d, m2l_thd=%d, l2m_thd=%d\n", __func__, als_ag_h2m_thd, als_ag_m2h_thd, als_ag_m2l_thd, als_ag_l2m_thd);
  return ret;
}
static int mn_sensor_read_ps_thd()
{
  int ret = -1;
  mn_sensor_I2C_Read(DEVREG_PS_ILTL, i2cData, 4);
  pilt = ((i2cData[1] << 8) | i2cData[0]);
  piht = ((i2cData[3] << 8) | i2cData[2]);
  //Serial.printf("[%s]: low_thd = %d, high_thd = %d \r\n", __func__, pilt, piht);
  return ret;
}
static int mn_sensor_report_als()
{
  if (als_timer_report_flag == true)
  {
    als_timer_report_flag = false;
    mn_sensor_read_als_ag_thd_data();
    mn78xxx_read_als();
    mn78_sensor_report_als();
  }
}
static int mn_sensor_report_ps()
{
  if (ps_timer_report_flag == true)
  {
    ps_timer_report_flag = false;
    mn_sensor_read_ps_thd();
    mn78xxx_read_ps();
    mn78_sensor_report_ps((mn_sensor_ps_compare_low >> 3));
  }
}
bool toggle_polling_reading(void *) {
  // printf("[%s]: xxxxxxxxxxxxxxxxx als/ps(%d/%d) \n", __func__, mn_sensor_als_polling_mode, mn78xxx_dev_als_enable);
  if ( (mn_sensor_als_polling_mode == true) && (mn78xxx_dev_als_enable == true) )
  {
    als_timer_report_flag = true;
  }

  if ( (mn_sensor_ps_polling_mode == true) && (mn78xxx_dev_ps_enable == true) )
  {
    ps_timer_report_flag = true;
  }
  alsps_oled_flag = true;
  alsps_TJC_flag = true;
  return true; // repeat? true
}
bool ps_dyn_k_timer(void *) {
  mn78xxx_read_ps();
  mn78_sensor_do_ps_auto_k();
  Serial.println("ps_dyn_k_timer start done ");
  return true; // repeat? true
}
void initmn78911()
{
  while (mn_sensor_I2C_Read(DEVREG_REV_ID, i2cData, 1));
  if (i2cData[0] != 0x88)
    while (1);
  Serial.print("DEVREG_REV_ID is 0x");
  Serial.println(i2cData[0], HEX);
  if ( (mn_sensor_als_polling_mode == true) && (mn_sensor_ps_polling_mode == true) )
    Serial.println("init polling done");
  else
  {
    pinMode(SensorINPUT, INPUT_PULLUP);
    attachInterrupt(SensorINPUT, mn78xxx_setup_eint, FALLING );
    Serial.println("init int done ");
    Serial.println(SensorINPUT);
  }
  if  ( (mn_sensor_als_polling_mode == true) | (mn_sensor_ps_polling_mode == true) )
  {
    timer.every(200, toggle_polling_reading);
    Serial.println("timer start done ");
  }
#if DEBUG_LOG
  timer.every(9000, print_message);//开启打印寄存器
#endif
#if (PS_DYN_K && PS_DYN_K_TIMER)
  timer.every(200, ps_dyn_k_timer);//开启打印寄存器
#endif
  initial_global_variable();
  set_lsensor_intr_threshold(1000, 999);
}
